package com.sky.service.impl;

import com.sky.dto.GoodsSalesDTO;
import com.sky.entity.Orders;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.ReportService;
import com.sky.service.WorkSpaceService;
import com.sky.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class ReportServiceImpl implements ReportService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private WorkSpaceService workSpaceService;

    /**
     * 营业额数据统计
     * @param begin 开始日期（2023-5-15）
     * @param end 结束日期（2023-5-21）
     * @return 日期列表（值之间用逗号隔开），营业额列表（值之间用逗号隔开）
     */
    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
        //1.获取日期字符串
        //2.定义集合，存储每一个日期
        ArrayList<LocalDate> dateList = new ArrayList<>();
        //3.从开始遍历到结束
        while (begin.compareTo(end) <= 0) {
            //4.将每天都存到集合中
            dateList.add(begin);
            begin = begin.plusDays(1);
        }
        //5.以逗号分隔，转成一个字符串
        String dates = StringUtils.join(dateList, ',');
        //6.获取营业额字符串
        //7.定义集合，存储营业额
        ArrayList<Double> amountList = new ArrayList<>();
        //8.遍历集合，获取每一个日期
        for (LocalDate localDate : dateList) {
            //9.查询当天营业额，存到集合中
            Double amount = orderMapper.getAmountByDateAndStatus(localDate, Orders.COMPLETED);
            amountList.add(amount == null ? 0.0 : amount);
        }
        String amounts = StringUtils.join(amountList, ',');
        return new TurnoverReportVO(dates, amounts);
    }

    /**
     * 用户数据统计
     * @param begin 开始日期（2023-5-15）
     * @param end 结束日期（2023-5-21）
     * @return
     * dateList 日期列表，以逗号分隔
     * newUserList 新增用户数列表，以逗号分隔
     * totalUserList 总用户量列表，以逗号分隔
     */
    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        ArrayList<LocalDate> localDates = new ArrayList<>();
        String dates = getDateList(begin, end, localDates);
        ArrayList<Integer> newUserList = new ArrayList<>();
        ArrayList<Integer> totalUserList = new ArrayList<>();
        Integer totalUser = userMapper.getTotalUserListBeforeDate(begin);
        for (LocalDate localDate : localDates) {
            Integer newUser = userMapper.getNewUserByDate(localDate);
            newUserList.add(newUser);
            //获取总数=某天之前一共的+某天新增的
            totalUser += newUser;
            totalUserList.add(totalUser);
        }
        String newUsers = StringUtils.join(newUserList, ",");
        String totalUsers = StringUtils.join(totalUserList, ",");
        return new UserReportVO(dates, totalUsers, newUsers);
    }

    /**
     * 订单数据统计
     * @param begin 开始日期（2023-5-15）
     * @param end 结束日期（2023-5-21）
     * @return
     * dateList    日期列表，以逗号分隔
     * orderCompletionRate 订单完成率
     * orderCountList 订单数列表，以逗号分隔
     * totalOrderCount 订单总数
     * validOrderCount 有效订单数
     * validOrderCountList 有效订单数列表，以逗号分隔
     */
    @Override
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {
        ArrayList<LocalDate> localDates = new ArrayList<>();
        String dates = getDateList(begin, end, localDates);
        //1.获取订单数量列表
        ArrayList<Integer> orderCountList = new ArrayList<>();
        //2.获取有效订单数列表
        ArrayList<Integer> validOrderCountList = new ArrayList<>();
        Integer totalCount = 0;
        Integer validTotalCount = 0;
        for (LocalDate localDate : localDates) {
            Integer orderCount = orderMapper.getCountByDateAndStatus(localDate, null);
            //3.获取订单总数
            totalCount += orderCount;
            Integer validOrderCount = orderMapper.getCountByDateAndStatus(localDate, Orders.COMPLETED);
            //4.获取有效订单数
            validTotalCount += validOrderCount;
            orderCountList.add(orderCount);
            validOrderCountList.add(validOrderCount);
        }
        //5..获取订单完成率
        double orderCompletionRate = 0.0;
        if (totalCount != 0) {
            orderCompletionRate = validTotalCount.doubleValue() / totalCount;
        }
        return new OrderReportVO(
                dates,//日期列表
                StringUtils.join(orderCountList, ","),//订单数量列表
                StringUtils.join(validOrderCountList, ","),//有效订单数列表
                totalCount,//订单总数
                validTotalCount,//有效订单数
                orderCompletionRate//订单完成率
        );
    }

    /**
     * 查询销量排名top10接口
     * @param begin 开始日期（2023-5-15）
     * @param end 结束日期（2023-5-21）
     * @return
     * nameList 商品名称列表，以逗号分隔
     * numberList 销量列表，以逗号分隔
     */
    @Override
    public SalesTop10ReportVO top(LocalDate begin, LocalDate end) {
        List<GoodsSalesDTO> goodsSalesDTOList = orderDetailMapper.top(begin, end);
        ArrayList<String> nameList = new ArrayList<>();
        ArrayList<Integer> numberList = new ArrayList<>();
        for (GoodsSalesDTO goodsSalesDTO : goodsSalesDTOList) {
            nameList.add(goodsSalesDTO.getName());
            numberList.add(goodsSalesDTO.getNumber());
        }
        return new SalesTop10ReportVO(
                StringUtils.join(nameList, ","),
                StringUtils.join(numberList, ",")
        );
    }

    /**
     * 导出Excel报表接口
     * @param response response
     */
    @Override
    public void export(HttpServletResponse response) {
        LocalDate begin = LocalDate.now().minusDays(30);
        LocalDate end = LocalDate.now().minusDays(1);
        //查询概览运营数据，提供给excel模板文件
        BusinessDataVO businessData = workSpaceService.businessData(
                LocalDateTime.of(begin, LocalTime.MIN),
                LocalDateTime.of(end, LocalTime.MAX)
        );
        FileInputStream is = null;
        try {
            is = new FileInputStream("D:\\take_out\\Class\\sky-take-out\\sky-server\\src\\main\\resources\\template\\运营数据报表模板.xlsx");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        //基于提供好的模板文件创建一个新的excel表格对象
        XSSFWorkbook excel = null;
        ServletOutputStream os = null;
        try {
            assert is != null;
            excel = new XSSFWorkbook(is);
            //获得excel文件中的一个sheet页
            XSSFSheet sheet = excel.getSheet("Sheet1");
            sheet.getRow(1).getCell(1).setCellValue(begin + "至" + end);
            //获得第四行
            XSSFRow row = sheet.getRow(3);
            //获取单元格
            row.getCell(2).setCellValue(businessData.getTurnover());
            row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
            row.getCell(6).setCellValue(businessData.getNewUsers());
            row = sheet.getRow(4);
            row.getCell(2).setCellValue(businessData.getValidOrderCount());
            row.getCell(4).setCellValue(businessData.getUnitPrice());
            for (int i = 0; i < 30; i++) {
                LocalDate localDate = begin.plusDays(i);
                //准备明细数据
                businessData = workSpaceService.businessData(
                        LocalDateTime.of(localDate, LocalTime.MIN),
                        LocalDateTime.of(localDate, LocalTime.MAX)
                );
                row = sheet.getRow(7 + i);
                row.getCell(1).setCellValue(localDate.toString());
                row.getCell(2).setCellValue(businessData.getTurnover());
                row.getCell(3).setCellValue(businessData.getValidOrderCount());
                row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
                row.getCell(5).setCellValue(businessData.getUnitPrice());
                row.getCell(6).setCellValue(businessData.getNewUsers());
            }
            //通过输出流将文件下载到客户端浏览器中
            os = response.getOutputStream();
            excel.write(os);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭资源
            try {
                if (os != null) {
                    os.flush();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (excel != null) {
                    excel.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取日期列表
     * @param begin 开始日期（2023-5-15）
     * @param end 结束日期（2023-5-21）
     * @return dateList 日期列表，以逗号分隔
     */
    private String getDateList(LocalDate begin, LocalDate end, ArrayList<LocalDate> localDates) {
        while (begin.compareTo(end) <= 0) {
            localDates.add(begin);
            begin = begin.plusDays(1);
        }
        return StringUtils.join(localDates, ",");
    }
}